package dominio;

/*Codigo creado por:
- Francisco Ruiz Romero 			05715573G
- Rosana Rguez-Bobada Aranda		70592974V
Escuela Superior de Informatica(ESI) - UCLM
*/

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;

import ncsa.hdf.object.Attribute;
import ncsa.hdf.object.Dataset;
import ncsa.hdf.object.Datatype;
import ncsa.hdf.object.FileFormat;
import ncsa.hdf.object.Group;
import ncsa.hdf.object.h5.H5File;

public class Util {
    static long IDnodo=1; 

    
    /* *********************************************************************************
     *************Métodos que calculan la Tarea 4 (funciones).**************************
    ********************************************************************************* */
    public static List<NodoBusqueda> procesarSucesores(Problema p,List<NodoBusqueda> LN){
    	int x,y;
    	List<NodoBusqueda> nodosValidos=new ArrayList<NodoBusqueda>();
    	double[][] matrizVisitados ;
    	NodoBusqueda nodo;
    	for(int i=0;i<LN.size();i++){
    		nodo=LN.get(i);
    		matrizVisitados=determinarHojaMatriz(nodo,p);
    		x=nodo.getEstado().getX();
    		y=nodo.getEstado().getY();
    		if(matrizVisitados[x][y]>nodo.getValoracion()){
    			nodosValidos.add(nodo);
    			matrizVisitados[x][y]=nodo.getValoracion();
    		}
    	}
    	return nodosValidos;
    	
    }   
    
    private static double[][] determinarHojaMatriz(NodoBusqueda nodo, Problema p){
    	double[][] matrizVisitados = null;
    	switch(nodo.getEstado().getHoja()){
    		case 711:
			matrizVisitados=p.getH711();
				break;
    		case 712:
    			matrizVisitados=p.getH712();
    			break;
    		case 736:
    			matrizVisitados=p.getH736();
    			break;
    		case 737:
    			matrizVisitados=p.getH737();
    			break;
    	}
    	return matrizVisitados;
    }

    public static void generarMatricesOptimizacion(Problema p) throws Exception {
    	int [] hojas={711,712,736,737};
    	List<double[][]> matrices=new ArrayList<double[][]>();
    	int[] dims;
    	double[][] matriz;
        for(int i=0;i<hojas.length;i++){
        	dims=recuperarDimensiones(hojas[i]);
        	matriz=new double[dims[1]][dims[0]];
        	initMatrizMaxValue(matriz);
        	matrices.add(matriz);
        };
        p.setH711(matrices.get(0));
        p.setH712(matrices.get(1));
        p.setH736(matrices.get(2));
        p.setH737(matrices.get(3));
	}
  
    private static void initMatrizMaxValue(double[][] m){
    	for(int i=0;i<m.length;i++){
    		for(int j=0;j<m[0].length;j++){
    			m[i][j]=Double.MAX_VALUE;
    		}
    	}	
    }
    
   
    
    
    /* *********************************************************************************
     *************Métodos que calculan la Tarea 3 (funciones).**************************
    ********************************************************************************* */
    
    public static List<NodoBusqueda> CrearListaNodosArbol(List<Estado> listaSucesores, String estrategia, NodoBusqueda nodo,Problema problema,boolean optimizacion) throws Exception{
            List<NodoBusqueda> listaNodos=new ArrayList<NodoBusqueda>();
            Estado es;
            for(int i=0;i<listaSucesores.size();i++){
                es=listaSucesores.get(i);
                NodoBusqueda nEs = new NodoBusqueda(IDnodo++,nodo,es,accion(es.getAcc()),nodo.getProf()+1,
                        Util.cambioSentido(nodo.getEstado().getAcc(),es.getAcc()),
                        nodo.getCosto()+calcularCosto(nodo.getEstado(),es));
                nEs.setValoracion(determinarValoracion(estrategia,nEs,problema.getMeta()));
                listaNodos.add(nEs);
            }
            if(optimizacion)listaNodos=procesarSucesores(problema,listaNodos);
            
            return listaNodos;
    }
    public static float determinarValoracion(String estrategia,NodoBusqueda nodo_actual,Estado meta) throws Exception{
    		float valoracion=0;
            switch (estrategia){
                    case "voraz":
                    		valoracion=calcularHeuristica(nodo_actual.getEstado(),meta);
                            break;
                    case "A":
                    		valoracion=nodo_actual.getCosto()+calcularHeuristica(nodo_actual.getEstado(),meta);
                            break;
                    case "anchura":
                    		valoracion=nodo_actual.getProf();
                            break;
                    case "profundidad":
                			valoracion=-nodo_actual.getProf();
                            break;
                    case "uniforme":
                    		valoracion=nodo_actual.getCosto();
                            break;
            }
            return valoracion;
    }
      
    /* *********************************************************************************
     *************Métodos auxiliares usados en la Tarea 3.******e********************
    ********************************************************************************* */
    
    public static List<NodoBusqueda> crearSolucion(NodoBusqueda nodo_final){
    	List<NodoBusqueda> solucion=new ArrayList<NodoBusqueda>();
    	while(nodo_final.getPadre()!=null){
    		solucion.add(nodo_final);
    		nodo_final=nodo_final.getPadre();
    	}
    	solucion.add(nodo_final);																																																																																																																								
    	return solucion;
    }
    
    
    public static float calcularCosto(Estado eO, Estado eD){ //Método que calcula el costo para llegar del estado origen al estado destino.
            float costo=0;
            double ld=0;
            double longitud=0;
            double incAlt=eD.getAltitud()-eO.getAltitud();
            if(eD.getAcc().length()==1){
                    ld=25;
            }else{
                    ld=Math.sqrt(2*Math.pow(25,2));
            }
                    
            longitud=Math.sqrt(Math.pow(ld,2)+Math.pow(incAlt,2));
            if(cambioSentido(eO.getAcc(), eD.getAcc())){
                    costo=(float) (longitud*1.1);
            }else{
                    costo=(float) longitud;
            }
            return costo;
    }
    
    public static float calcularHeuristica(Estado eD, Estado eN) throws Exception{ //Método para calcular la heur�stica de un estado n al estado destino.
            int [] UTMeD=coordenadasUTM(eD.getHoja(), eD.getX(),eD.getY());
            int [] UTMeN=coordenadasUTM(eN.getHoja(), eN.getX(),eN.getY());
            return (float) Math.sqrt(Math.pow(UTMeD[0]-UTMeN[0],2)+Math.pow(UTMeD[1]-UTMeN[1],2));
    }
    
    
    /* *********************************************************************************
     *************Métodos auxiliares usados en la Tarea 2.**************************
    ********************************************************************************* */
    public static boolean cambioSentido(String accEsOrigen, String accEsDestino){ //Método que determina si se ha producido un cambio de sentido.
            boolean cambio=true;
            if(accEsOrigen.equals(accEsDestino)) cambio=false;
            return cambio;
    }
  
        public static String accion(String a){//Método que devuelve la acci�n a realzar para llegar a un estado
        	String acc = null;
        	switch(a){
        		case "N":
        			acc="S";
        			break;
        		case "NE":
        			acc="SO";
        			break;
        		case "E":
        			acc="O";
        			break;
        		case "SE":
        			acc="NO";
        			break;
        		case "S":
        			acc="N";
        			break;
        		case "SO":
        			acc="NE";
        			break;
        		case "O":
        			acc="E";
        			break;
        		case "NO":
        			acc="SE";
        			break;
        	}
        	return acc;
        }
        
        
        /* *********************************************************************************
         *************Métodos que calculan la Tarea 1 (funciones).**************************
        ********************************************************************************* */
                
                //La funci�n meta se encuentra dentro de la clase Problema
                
                public static List<Estado>  Sucesor(Estado es) throws Exception{
                        List<Estado> LS=new ArrayList<Estado>();
                        Estado sucesor;
                        for(int i=0;i<8;i++){
                                sucesor=calcularSucesor(es,i);
                                if(sucesor!=null) LS.add(sucesor);
                        }
                        return LS;
                }
                
                //Metodo que calcula el sucesor correspondiente dada una accion
                private static Estado calcularSucesor(Estado es, int i) throws Exception{
                        Estado e = null;
                        switch(i){
                                case 0:
                                        if(comprobarHoja(es.getHoja(),es.getX(),es.getY()+1)){
                                                e=new Estado(es.getHoja(),es.getX(),es.getY()+1,altitud(es.getHoja(),es.getX(),es.getY()+1), "S");
                                        }else{
                                                if(es.getHoja()==736 || es.getHoja()==737){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),0,+25,"S");
                                                }else{
                                                        e=null;
                                                }
                                        }
                                        break;
                                        
                                case 1:
                                        if(comprobarHoja(es.getHoja(),es.getX()+1,es.getY()+1)){
                                                e=new Estado(es.getHoja(),es.getX()+1,es.getY()+1,altitud(es.getHoja(),es.getX()+1,es.getY()+1), "SO");
                                        }else{
                                                if(es.getHoja()==736 || es.getHoja()==737){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),+25,+25,"SO");
                                                }else{
                                                        e=null;
                                                }
                                        }
                                        break;
                                        
                                case 2:
                                        if(comprobarHoja(es.getHoja(),es.getX()+1,es.getY())){
                                                e=new Estado(es.getHoja(),es.getX()+1,es.getY(),altitud(es.getHoja(),es.getX()+1,es.getY()), "O");
                                        }else{
                                                if(es.getHoja()==711 || es.getHoja()==736){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),+25,0,"O");
                                                }else{
                                                        e=null;
                                                }
                                        }
                                        break;
                                        
                                case 3:
                                        if(comprobarHoja(es.getHoja(),es.getX()+1,es.getY()-1)){
                                                e=new Estado(es.getHoja(),es.getX()+1,es.getY()-1,altitud(es.getHoja(),es.getX()+1,es.getY()-1), "NO");
                                        }else{
                                                if(es.getHoja()==711 || es.getHoja() == 712){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),+25,-25,"NO");
                                                }else{
                                                        e=null;
                                                }
                                        }
                                        break;
                                        
                                case 4:
                                        if(comprobarHoja(es.getHoja(),es.getX(),es.getY()-1)){
                                                e=new Estado(es.getHoja(),es.getX(),es.getY()-1,altitud(es.getHoja(),es.getX(),es.getY()-1), "N");
                                        }else{
                                                if(es.getHoja()==711 || es.getHoja()==712){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),0,-25,"N");
                                                }else{
                                                        e=null;
                                                }       
                                        }
                                        break;
                                        
                                case 5:
                                        if(comprobarHoja(es.getHoja(),es.getX()-1,es.getY()-1)){
                                                e=new Estado(es.getHoja(),es.getX()-1,es.getY()-1,altitud(es.getHoja(),es.getX()-1,es.getY()-1), "NE");
                                        }else{
                                                if(es.getHoja()==711 || es.getHoja()==712){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),-25,-25,"NE");
                                                }else{
                                                        e=null;
                                                }       
                                        }
                                        break;
                                        
                                case 6:
                                        if(comprobarHoja(es.getHoja(),es.getX()-1,es.getY())){
                                                e=new Estado(es.getHoja(),es.getX()-1,es.getY(),altitud(es.getHoja(),es.getX()-1,es.getY()), "E");
                                        }else{
                                                if(es.getHoja()==712 || es.getHoja()==737){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),-25,0,"E");
                                                }else{
                                                        e=null;
                                                }
                                        }
                                        break;
                                        
                                case 7:
                                        if(comprobarHoja(es.getHoja(),es.getX()-1,es.getY()+1)){
                                                e=new Estado(es.getHoja(),es.getX()-1,es.getY()+1,altitud(es.getHoja(),es.getX()-1,es.getY()+1), "SE");
                                        }else{
                                                if(es.getHoja()==736 || es.getHoja()==737){
                                                        e=calcularEstado(es.getHoja(), es.getX(), es.getY(),-25,+25,"SE");
                                                }else{
                                                        e=null;
                                                }
                                        }
                                        break;
                                        
                        }
                        return e;
                }
                
                /*Este  metodo ha sido implementado debido a que en el metodo calcularSucesor
                se repetia este código dentro de cada case en el switch*/
                private static Estado calcularEstado(int hoja, int x, int y, int incx, int incy, String acc) throws Exception{
                        Estado e;
                        int [] coordenadas=coordenadasUTM(hoja,x,y);
                        int [] lGeografico=lugarGeografico(coordenadas[0]+incx,coordenadas[1]+incy);
                        if(lGeografico!=null){
                                e=new Estado(lGeografico[0],lGeografico[1],lGeografico[2],altitud(lGeografico[0],lGeografico[1],lGeografico[2]), acc);
                        }else{
                                e=null;
                        }
                        return e;
                }
                
                //Metodo que comprueba si unas posiciones de matriz pertenecen a una hoja
                private static boolean comprobarHoja(int hoja, int x,int y) throws Exception{
                        boolean b=false;
                        int[] dimension;
                        dimension=recuperarDimensiones(hoja);
                        if(x>=0 && x<dimension[1] && y>=0 && y<dimension[0]){
                                b=true;
                        }
                        return b;
                }
                
                //Metodo que recoge del fichero HDF5, ncols y nrows de la hoja dada
                private static int[] recuperarDimensiones(int hoja) throws Exception{
                        int []v=new int[2];
                        Dataset dataset;
                        int i=0;
                        //Instanciamos el archivo para recuperar nrows y ncols
                        FileFormat testFile=instanciar("Datos.h5", FileFormat.READ);
                        testFile.open();
                        //Cogemos el grupo que contiene las distintas hojas con las que trabajaremos
                        Group g1 = (Group) ((javax.swing.tree.DefaultMutableTreeNode) testFile.getRootNode()).getNextNode().getUserObject();
                        //Vamos recorriendo cada dataset hasta que encontremos el que corresponde a la hoja
                        do{
                        	dataset = (Dataset) g1.getMemberList().get(i++);
                        }while(Integer.parseInt(dataset.getName())!=hoja);
                        //Cogemos nrows(v[0]) y ncols(v[1])
                        v[0]=Integer.parseInt(((Attribute)dataset.getMetadata().get(2)).toString(" "));
                        v[1]=Integer.parseInt(((Attribute)dataset.getMetadata().get(1)).toString(" "));
                        return v;
                }
        
        /* *********************************************************************************
        *************Métodos que calculan las Tareas 0.1 y 0.2 (funciones).**************
        ********************************************************************************* */

        public static double altitud(int hoja, int x, int y) throws Exception{
                //Declaracion de variables
                double altitud;
                int i=0, hojaData,ncols,nrows;
                double[] vectorAltitud;
                Dataset dataset;
                //Instanciamos el archivo HDF5 en modo Lectura y lo abrimos
                FileFormat testFile=instanciar("Datos.h5", FileFormat.READ);
                testFile.open();
                //Cogemos el grupo que contiene las distintas hojas con las que trabajaremos
                Group g1 = (Group) ((javax.swing.tree.DefaultMutableTreeNode) testFile.getRootNode()).getNextNode().getUserObject();
                //Buscamos el dataset que corresponde con la hoja introducida como atributo 
                do{
                	hojaData =  Integer.parseInt(g1.getMemberList().get(i++).getName());
                }while(hojaData != hoja);
                //Una vez encontrada, la abrimos, cogemos el vector de altitudes y cogemos la posicion correspondiente.
                dataset=(Dataset) g1.getMemberList().get(--i);
                vectorAltitud=(double[]) dataset.read();
                ncols=(Integer.parseInt(((Attribute)dataset.getMetadata().get(1)).toString(" ")));
                nrows=(Integer.parseInt(((Attribute)dataset.getMetadata().get(2)).toString(" ")));
                altitud=vectorAltitud[(nrows-1)*ncols-y*ncols+x];
                // Cerramos el fichero.
                testFile.close();
                //Devolvemos la altitud
                return altitud;
        }
                
        public static int[] lugarGeografico(int px, int py) throws Exception{
                //Declaracion de variables
                int [] datos=new int [3]; 
                int [] limites;
                int pos[]=new int[2];
                int [] atributos=null;
                int k=0;
                boolean dentro;
                //Instanciamos el archivo HDF5 en modo Lectura y lo abrimos  
                FileFormat testFile=instanciar("Datos.h5", FileFormat.READ);
                testFile.open();
                //Cogemos el grupo que contiene las distintas hojas con las que trabajaremos
                Group g1 = (Group) ((javax.swing.tree.DefaultMutableTreeNode) testFile.getRootNode()).getNextNode().getUserObject();
                //Vamos recorriendo cada dataset hasta que encontremos uno donde el punto est� dentro
                do{
                	//Recuperamos un dataset
                	Dataset dataset = (Dataset) g1.getMemberList().get(k++);
                	//Leemos los atributos del dataset
                	atributos=cargarAtributos(dataset.getMetadata());       
                	//Coger solo los limites entre los atributos
                	limites=separarLimites(atributos);
                	//Comprobamos si el punto pertenece a esa celda. Si no pertenece, volvemos arriba a repetir el proceso con otra celda.
                	dentro=comprobarLimites(px,py,limites);
                }while(!dentro && k<4);
                //Si hemos encontrado una hoja a la que pertenecen las coordenadas
                if(dentro){
                	//Obtenemos la posici�n correspondiente al punto en la matriz.
                	pos=obtenerPosicionMatriz(px,py,atributos,limites);
                	//Guardamos en la estructura los datos a devolver
                	datos[0]=atributos[0];
                	datos[1]=pos[0];
                	datos[2]=pos[1];
                }else{//Si no la hemos encontrado, devolvemos un null.
                	datos=null;
                }
                // Cerramos el fichero.
                testFile.close();
                //Devolvemos los resultados
                return datos;
                }
        
        private static FileFormat instanciar(String nombre, int formato) throws Exception{
                //Recuperamos la instancia
        FileFormat fileFormat = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5);
        //Abrimos el archivo con el formato indicado por argumentos
        FileFormat testFile = fileFormat.createInstance(nombre, formato);
        return testFile;
        }
        
        private static int[] cargarAtributos( List<?> attrList){// Metodo para almacenar en un vector de enteros los atributos de cada hoja
                //Convertimos a entero cada uno de los atributos ya que dentro del archivo H5 son strings.
                int[] valores={(Integer.parseInt(((Attribute)attrList.get(0)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(1)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(2)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(3)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(4)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(5)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(6)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(7)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(8)).toString(" "))),
                                   (Integer.parseInt(((Attribute)attrList.get(9)).toString(" "))),};
                return valores;
        }
        
        private static boolean comprobarLimites(int x, int y, int[] limites){//Método que comprueba los l�mites de la hoja.
                boolean comprobar=false;
                if(x>=limites[0] && x<=limites[1] && y>=limites[2] && y<=limites[3]) comprobar=true;
                return comprobar;
        }
        
        private static int[] separarLimites(int[] v){
                int[] limites={v[4],v[6],v[7],v[9]};
                return limites;
        }
        
        private static int[] obtenerPosicionMatriz(int px, int py, int [] valores,int [] limites){//Método que obtine la posici�n de la matriz.
                int[] posicion={(px-limites[0])/valores[3],(py-limites[2])/valores[3]};
                return posicion;
        }
        
        public static int [] coordenadasUTM(int hoja,int x, int y) throws Exception{
                Dataset dataset;
                int i=0;
                //Instanciamos el archivo para recuperar nrows y ncols
                FileFormat testFile=instanciar("Datos.h5", FileFormat.READ);
                testFile.open();
                //Cogemos el grupo que contiene las distintas hojas con las que trabajaremos
                Group g1 = (Group) ((javax.swing.tree.DefaultMutableTreeNode) testFile.getRootNode()).getNextNode().getUserObject();
                //Vamos recorriendo cada dataset hasta que encontremos el que corresponde a la hoja
                do{
                	dataset = (Dataset) g1.getMemberList().get(i++);
                }while(Integer.parseInt(dataset.getName())!=hoja);
                //Cogemos los atributos de ese dataset 
                int [] v= cargarAtributos(dataset.getMetadata()); 
                int[] coorUTM={v[5]+x*v[3], v[8]+y*v[3]};
                return coorUTM ;
        }
        
        
        /* ********************************************************************************
        **************Métodos para obtener los datos de los archios *.asc.***************
        ********************************************************************************* */
        
        public static void createFile(String fname, String[] nomFich)throws Exception {//Creamos el fichero H5 con todos los datos.
                //Declaracion de variables
                Celda c=null;
                long[] dimension = new long[2];
                long []attrDims ={1};
                Attribute attr=null ;
                int [] limites=null;
                String [] variables= { "hoja", "ncols", "nrows", "tamcel","xllcenter", "yllcenter","xinf","xsup","yinf","ysup" };
                // Recuperar la instancia del fichero.
                FileFormat fileFormat = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5);
                // Crear un nuevo fichero a partir del nombre dado.
                H5File testFile = (H5File) fileFormat.createFile(fname, FileFormat.FILE_CREATE_DELETE);
                // Abrir fichero y recuperar la instacia del root.
                testFile.open();
                Group root = (Group) ((javax.swing.tree.DefaultMutableTreeNode) testFile.getRootNode()).getUserObject();
                // Creamos un grupo que contendr� las cuatro hojas.
                Group g1 = testFile.createGroup("Hojas", root);
                // A�adimos los ficheros *.asc al grupo.
                for (int i = 0; i < nomFich.length; i++) {
                        //Leemos los datos de cada fichero .asc y lo almacenamos en un objeto de tipo Celda
                        c = Util.leerASC(nomFich[i]);
                        //Rellenamos los vectores de valores y el de dimensi�n para utilizarlos posteriormente
                        int []valores={c.getHoja(),c.getNcols(), c.getNrows(),c.getTamcel(),c.getXllcenter(), c.getYllcenter()};
                        limites=establecerLimites(valores);
                        dimension[0] = c.getNrows();
                        dimension[1] = c.getNcols();
                        //Creamos el tipo de dato que vamos a usar dentro del dataset y lo creamos indicandole el nombre, el tipo de dato, la dimensi�n y el vector de datos que almacenar�
                        Datatype dtype = testFile.createDatatype(Datatype.CLASS_FLOAT, 8,Datatype.NATIVE, Datatype.NATIVE);
                        Dataset dataset = testFile.createScalarDS(Integer.toString(c.getHoja()),g1, dtype, dimension, null,null, 0, c.getVector());
                        //Creamos el tipo de dato que vamos a usar como atributos del dataset.
                        Datatype dtypeAt = testFile.createDatatype(Datatype.CLASS_INTEGER,4,Datatype.NATIVE, Datatype.NATIVE);
                        //Vamos a�adiendo los atributos a su dataset correspondiente
                        for(int j=0;j<variables.length-4;j++){
                                attr= new Attribute(variables[j], dtypeAt, attrDims);
                                long[] at={valores[j]};
                                attr.setValue(at);
                                dataset.writeMetadata(attr);
                }
                        for (int j=6;j<variables.length;j++){
                                attr= new Attribute(variables[j], dtypeAt, attrDims);
                                long[] at={limites[j-6]};
                                attr.setValue(at);
                                dataset.writeMetadata(attr);
                
                        }
                }
                
                // Cerramos el fichero.
                testFile.close();
        }
        
        private static Celda leerASC(String nombreFichero) { // Método para leer el archivo MDT.
                //Declaracion de variables
                double[]vector;
                File archivo=null;
                Scanner leer = null;
                Celda datoCelda = null;
                //Abrimos un archivo *.asc y creamos un objeto de tipo Celda con los datos leidos
                try {
                        archivo = new File(nombreFichero);
                        leer = new Scanner(archivo).useLocale(Locale.US);
                        datoCelda=new Celda(leerValor(leer),leerValor(leer),leerValor(leer),leerValor(leer),leerValor(leer),Integer.parseInt(archivo.getName().split("-")[1]));
                        vector = datosAltitud(leer, datoCelda.getNcols(), datoCelda.getNrows());
                        datoCelda.setVector(vector);
                } catch (Exception e) {
                        System.out.println(e);
                }
                leer.close();
                //Devolvemos la Celda creada
                return datoCelda;
        }
                
        private static double[] datosAltitud(Scanner leer, int ncols, int nrows) {//Método que obtiene la matriz de altitudes.
                //Declaracion de variables
                double[] vector = new double[nrows*ncols];
                int i=0,j = 0;
                leer.next(); // Saltamos el nondatavalue.
                leer.nextLine();
                //Creamos el vector correspondiente a la matriz perteneciente al fichero asc para poder a�adirlo al .H5
                for (i = 0; i < nrows; i++) {
                        for (j = 0; j < ncols; j++) {
                                vector[i*ncols+j] = leer.nextDouble();
                        }       
                }
                //Devolvemos el vector
                return vector;
        }

        private static int leerValor(Scanner leer) { // Método que devuelve el entero deseado a partir de la l�nea que lee del fichero
                int valor;
                leer.next();
                valor = leer.nextInt();
                return valor;
        }
        
        private static int[] establecerLimites(int [] v){//Método que establece los l�mites de la hoja.
                int[] limites=new int[4];
                limites[0]=v[4]-v[3]/2 ; //Limite X inferior
                limites[1]=v[4]+(v[1]-1)*v[3]+v[3]/2; //Limite X superior.
                limites[2]=v[5]-v[3]/2; //Limite Y inferior
                limites[3]=v[5]+(v[2]-1)*v[3]+v[3]/2;//Limite Y superior.
                return limites;
        }        
}